package com.example.previewvideo;

import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.graphics.SurfaceTexture;
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraCaptureSession;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CameraDevice;
import android.hardware.camera2.CameraManager;
import android.hardware.camera2.CameraMetadata;
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.params.StreamConfigurationMap;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.util.Size;
import android.view.Surface;
import android.view.TextureView;
import android.widget.ImageButton;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;

import com.blankj.utilcode.util.AppUtils;
import com.blankj.utilcode.util.LogUtils;
import com.blankj.utilcode.util.Utils;
import com.example.demo.R;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;

public class Camera3VideoCaptureActivity extends AppCompatActivity {

    private static final String TAG = "Camera3VideoCaptureActivity";

    private static final int REQUEST_CAMERA_PERMISSION = 1;

    private CameraManager cameraManager;
    private String cameraId;
    private CameraDevice cameraDevice;
    private CameraCaptureSession captureSession;
    private Size previewSize;

    private MediaRecorder mediaRecorder;
    private boolean isRecording = false;

    private TextureView textureView;
    private ImageButton btnRecord;

    int desiredWidth = 1920;
    int desiredHeight = 1080;

    int recordTime = 20 * 1000;//秒
    int fps = 24;

    //1Mbps等于每秒传输1兆比特（即1,000,000比特
    //    int bitRate = 100 * 1000000;// 100 Mbps
    int bitRate = 5000 * 1000;//  Mbps

    private Handler handler;
    private Runnable stopRecordingRunnable;
    private int segmentCount = 0;
    private long recordingStartTime;
    private static final long SEGMENT_DURATION_MS = 5000; // 60 seconds per segment
    private Runnable restartRecordingRunnable;
    private static final int MAX_DURATION_MS = 10*1000; // 最大录制时间，例如60秒
    int  count = 0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_camera2videocapture);

        textureView = findViewById(R.id.textureView);
        btnRecord = findViewById(R.id.btnRecord);
        btnRecord.setOnClickListener(v -> {
            if (isRecording) {
                stopRecording();
            } else {
                startRecording();
            }
        });

        cameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
        textureView.setSurfaceTextureListener(surfaceTextureListener);


        handler = new Handler(Looper.getMainLooper());
        restartRecordingRunnable = new Runnable() {
            @Override
            public void run() {
                count++;
                LogUtils.i(TAG,"startRecording  restartRecordingRunnable count: "+count);

                startRecording();
            }
        };
    }


    private TextureView.SurfaceTextureListener surfaceTextureListener = new TextureView.SurfaceTextureListener() {
        @Override
        public void onSurfaceTextureAvailable(@NonNull SurfaceTexture surface, int width, int height) {
            openCamera();
        }

        @Override
        public void onSurfaceTextureSizeChanged(@NonNull SurfaceTexture surface, int width, int height) {
            // Ignored, Camera does not support resizing
        }

        @Override
        public boolean onSurfaceTextureDestroyed(@NonNull SurfaceTexture surface) {
            return false;
        }

        @Override
        public void onSurfaceTextureUpdated(@NonNull SurfaceTexture surface) {
            // Invoked every time there's a new Camera preview frame
        }
    };

    private void openCamera() {
        try {
            cameraId = cameraManager.getCameraIdList()[0]; // Use the first camera available

            if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
                ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, REQUEST_CAMERA_PERMISSION);
                return;
            }
            setUpCameraOutputs();
            cameraManager.openCamera(cameraId, new CameraDevice.StateCallback() {
                @Override
                public void onOpened(@NonNull CameraDevice camera) {
                    cameraDevice = camera;

                    LogUtils.i(TAG, "cameraManager onOpened  ");

                    createCameraPreview();
                }

                @Override
                public void onDisconnected(@NonNull CameraDevice camera) {

                    LogUtils.i(TAG, "cameraManager onDisconnected  ");
                    cameraDevice.close();
                    cameraDevice = null;
                }

                @Override
                public void onError(@NonNull CameraDevice camera, int error) {
                    LogUtils.i(TAG, "cameraManager onError  " + error);
                    cameraDevice.close();
                    cameraDevice = null;
                }
            }, null);
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
    }

    private void createCameraPreview() {
        try {
            SurfaceTexture texture = textureView.getSurfaceTexture();


            texture.setDefaultBufferSize(previewSize.getWidth(), previewSize.getHeight());

            Surface surface = new Surface(texture);
            LogUtils.i(TAG, "createCameraPreview cameraDevice  " + cameraDevice);
            final CaptureRequest.Builder previewRequestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
            previewRequestBuilder.addTarget(surface);

            cameraDevice.createCaptureSession(Collections.singletonList(surface), new CameraCaptureSession.StateCallback() {
                @Override
                public void onConfigured(@NonNull CameraCaptureSession session) {
                    LogUtils.i(TAG, "createCaptureSession onConfigured  ");
                    captureSession = session;
                    try {
                        previewRequestBuilder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO);
                        captureSession.setRepeatingRequest(previewRequestBuilder.build(), null, null);
                    } catch (CameraAccessException e) {
                        e.printStackTrace();
                    }
                }

                @Override
                public void onConfigureFailed(@NonNull CameraCaptureSession session) {
                    LogUtils.i(TAG, "createCaptureSession onConfigureFailed  ");
                    Toast.makeText(Camera3VideoCaptureActivity.this, "Failed to create camera preview", Toast.LENGTH_SHORT).show();
                }
            }, null);
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
    }


    public void startRecording() {

        isRecording = true;
        mediaRecorder = new MediaRecorder();
        // 配置MediaRecorder
//        mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
//        mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
//        mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);



        mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
        mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
        mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
//
        // 设置要用于录制的音频源。
//        mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
//        // 设置要用于录制的视频源。
//        mediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
//        // 设置录制期间生成的输出文件的格式。
//        mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);

        // 设置要捕获的视频的帧速率。
        mediaRecorder.setVideoFrameRate(fps);
        mediaRecorder.setVideoSize(desiredWidth, desiredHeight);
        // 设置要用于录制的视频编码器。
        mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
        // 设置要用于录制的音频编码器。
        mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
//        mediaRecorder.setAudioSamplingRate(44); // 设置音频采样率为44
//        mediaRecorder.setAudioEncodingBitRate(64); // 设置音频比特率为64

        //设置录制视频编码比特率 10000000

        mediaRecorder.setVideoEncodingBitRate(bitRate);

        mediaRecorder.setOutputFile(getOutputMediaFile().getAbsolutePath());
//        mediaRecorder.setMaxDuration(MAX_DURATION_MS);
LogUtils.i(TAG,"startRecording: "+count);
//        mediaRecorder.setOnInfoListener(new MediaRecorder.OnInfoListener() {
//            @Override
//            public void onInfo(MediaRecorder mr, int what, int extra) {
//                LogUtils.i(TAG,"startRecording  what: "+what);
//                if (what == MediaRecorder.MEDIA_RECORDER_INFO_MAX_DURATION_REACHED) {
//                    // 达到最大录制时间，停止录制
//                    mediaRecorder.stop();
//                    mediaRecorder.reset();
//                    mediaRecorder.release();
//                    // 启动新的录制
//                    handler.post(restartRecordingRunnable);
//                }
//            }
//        });


        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                LogUtils.i(TAG,"startRecording  postDelayed: ");
                // 达到最大录制时间，停止录制
                stopRecording();
                // 启动新的录制
                handler.post(restartRecordingRunnable);

            }
        },MAX_DURATION_MS);



        try {
            mediaRecorder.prepare();
            mediaRecorder.start();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void stopRecording() {
        if (mediaRecorder != null) {
            mediaRecorder.stop();
            mediaRecorder.reset();
            mediaRecorder.release();
            mediaRecorder = null;
        }
        isRecording = false;

        handler.removeCallbacksAndMessages(null);
//        handler.removeCallbacksAndMessages(restartRecordingRunnable);
    }



    private File getOutputMediaFile() {
        String directoryPath = getCacheDir().getAbsolutePath() + "/videoNameC/";
        File mediaStorageDir = new File(directoryPath);
        if (!mediaStorageDir.exists()) {
            if (!mediaStorageDir.mkdirs()) {
                return null;
            }
        }
        String timestamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
        return new File(mediaStorageDir.getPath() + File.separator +
                "VID_" + timestamp + "_" + desiredWidth + "_" + desiredHeight + "_" + fps + "_" + bitRate  +count+ ".mp4");
    }

    private void setUpCameraOutputs() {
        try {
            CameraCharacteristics characteristics = cameraManager.getCameraCharacteristics(cameraId);
            StreamConfigurationMap map = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);

            // 获取支持的预览尺寸列表
            Size[] outputSizes = map.getOutputSizes(SurfaceTexture.class);

            // 选择最合适的预览尺寸，这里可以根据需要进行适当的逻辑处理
            previewSize = chooseOptimalSize(outputSizes, desiredWidth, desiredHeight);
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
    }

    private Size chooseOptimalSize(Size[] choices, int width, int height) {
        List<Size> bigEnough = new ArrayList<>();
        for (Size option : choices) {
            if (option.getWidth() >= width && option.getHeight() >= height) {
                bigEnough.add(option);
            }
        }
        if (bigEnough.size() > 0) {
            return Collections.min(bigEnough, new Comparator<Size>() {
                @Override
                public int compare(Size lhs, Size rhs) {
                    return Long.signum((long) lhs.getWidth() * lhs.getHeight() - (long) rhs.getWidth() * rhs.getHeight());
                }
            });
        } else {
            return choices[0]; // 如果没有合适的尺寸，返回默认的第一个尺寸
        }
    }



}

